#include <iostream>
#include <climits>
#include <limits>
#include <vector>
#include <algorithm>
using namespace std;

// 冒泡排序 
void BubbleSort(vector<int>& v, int n)
{
  for(int i = n - 1; i >= 1; --i)
  {
    bool flag = true;
    for(int j = 0; j < i; ++j)
    {
      if(v[j] > v[j + 1])
      {
        std::swap(v[j], v[j + 1]);
        flag = false;
      }
    }
    if(flag) break;
  }
}

// 快速排序
int GetMidIndex(vector<int>& v, int left, int right)
{
  int mid = left + (right - left) / 2;
  if(v[left] < v[mid])
  {
    if(v[right] < v[left]) return left;
    else if(v[mid] < v[right]) return mid;
    else return right;
  }
  else
  {
    if(v[right] > v[left]) return left;
    else if(v[mid] > v[right]) return mid;
    else return right;
  }
}

int PartSort(vector<int>& v, int left, int right)
{
  int mid = GetMidIndex(v, left, right);
  std::swap(v[mid], v[right]);
  int index = right;
  int key = v[right];
  while(left < right)
  {
    while(left < right && v[left] <= key) ++left;
    while(left < right && v[right] >= key) --right;
    std::swap(v[left], v[right]);
  }
  std::swap(v[left], v[index]);
  return left;
}

void QuickSort(vector<int>& v, int left, int right)
{
  if(left >= right) return;
  int div = PartSort(v, left, right);
  QuickSort(v, left, div - 1);
  QuickSort(v, div + 1, right);
}

// 插入排序
void InsertSort(vector<int>& v, int n)
{
  for(int i = 1; i < n; ++i)
  {
    int end = i - 1;
    int newBoard = v[i];
    while(end >= 0)
    {
      if(v[end] > newBoard) 
      {
        v[end + 1] = v[end];
        --end;
      }
      else
      {
        break;
      }
    }
    v[end + 1] = newBoard;
  }
}

// 希尔排序
void ShellSort(vector<int>& v, int n)
{
  int gap = n;
  while(gap > 1)
  {
    gap = gap / 3 + 1;
    for(int i = gap; i < n; ++i)
    {
      int end = i - gap;
      int newBoard = v[i];
      while(end >= 0)
      {
        if(v[end] > newBoard)
        {
          v[end + gap] = v[end];
          end -= gap;
        }
        else 
        {
          break;
        }
      }
      v[end + gap] = newBoard;
    }
  }
}

// 选择排序 
void SelectSort(vector<int>& v, int n)
{
  int begin = 0, end = n - 1;
  while(begin < end)
  {
    int minIndex = begin;
    int maxIndex = end;
    for(int i = begin; i <= end; ++i)
    {
      if(v[i] < v[minIndex]) minIndex = i;
      if(v[i] > v[maxIndex]) maxIndex = i;
    }
    std::swap(v[begin], v[minIndex]);
    if(begin == maxIndex) maxIndex = minIndex;
    std::swap(v[maxIndex], v[end]);
    ++begin, --end;
  }
}

// 堆排序
void AdjustDown(vector<int>& v, int n, int root)
{
  int parent = root;
  int child = parent * 2 + 1;
  while(child < n)
  {
    if(child + 1 < n && v[child + 1] > v[child]) ++child;

    if(v[child] > v[parent])
    {
      std::swap(v[child], v[parent]);
      parent = child;
      child = parent * 2 + 1;
    }
    else break;
  }
}

void HeapSort(vector<int>& v, int n)
{
  // 1、建队
  for(int i = (n - 1 - 1) / 2; i >= 0; --i)
  {
    AdjustDown(v, n, i);
  }

  // 2、排序
  for(int i = n - 1; i >= 1; --i)
  {
    std::swap(v[0], v[i]);
    AdjustDown(v, i, 0);
  }
}

// 归并排序
void MergeArray(vector<int>& v, int begin1, int end1, int begin2, int end2, vector<int>& tmp)
{
  int left = begin1, right = end2;
  int index = begin1;
  while(begin1 <= end1 && begin2 <= end2)
  {
    if(v[begin1] < v[begin2]) 
      tmp[index++] = v[begin1++];
    else 
      tmp[index++] = v[begin2++];
  }
  
  while(begin1 <= end1) tmp[index++] = v[begin1++];
  while(begin2 <= end2) tmp[index++] = v[begin2++];

  for(int i = left; i <= right; ++i) v[i] = tmp[i];
}

void _MergeSort(vector<int>& v, int left, int right, vector<int>& tmp)
{
  if(left >= right) return;
  int div = left + (right - left) / 2;
  _MergeSort(v, left, div, tmp);
  _MergeSort(v, div + 1, right, tmp);
  MergeArray(v, left, div, div + 1, right, tmp);
}

void MergeSort(vector<int>& v, int n)
{
  vector<int> tmp(n);
  _MergeSort(v, 0, n - 1, tmp);
}

// 计数排序
void CountSort(vector<int>& v, int n)
{
  int minValue = INT_MAX, maxValue = INT_MIN;
  for(const auto e : v)
  {
    if(e < minValue) minValue = e;
    if(e > maxValue) maxValue = e;
  }
  long long range = maxValue - minValue + 1;
  vector<int> count(range);
  for(const auto e : v) ++count[e - minValue];
  int index = 0;
  for(long long i = 0; i < range; ++i)
  {
    while(count[i]--)
    {
      v[index++] = minValue + i;
    }
  }
}

int main()
{
    int n = 0;
    cin >> n;
    vector<int> v(n);
    for(auto& e : v) cin >> e;

    //BubbleSort(v, n);
    //QuickSort(v, 0, n - 1);
    //InsertSort(v, n);
    //ShellSort(v, n);
    //SelectSort(v, n);
    //HeapSort(v, n);
    //MergeSort(v, n);
    CountSort(v, n);
    
    //reserve(v.begin(), v.end());

    for(int i = 0; i < n; ++i)
    {
        if(n != n - 1)
            cout << v[i] << ' ';
        else
            cout << v[i] << endl;
    }
}
